import pygtk, gtk, pango

class NoteBuffer(gtk.TextBuffer) :
    active_tags = []

    def __init__(self):
        gtk.TextBuffer.__init__(self)

        self.recreate_bold()
        self.recreate_italic()
        self.recreate_underline()
        self.recreate_font()
        self.recreate_link()

        # The font tag should always be active.
        self.active_tags.append(self.font_tag)

        self.connect_after('insert-text', self.on_text_inserted)

        self.note_id = 0

    def cut_text(self, textview) :
        self.cut_clipboard(gtk.clipboard_get(), textview.get_editable())

    def copy_text(self) :
        self.copy_clipboard(gtk.clipboard_get())

    def paste_text(self, textview) :
        self.paste_clipboard(gtk.clipboard_get(), None, textview.get_editable())

    def delete_text(self, textview) :
       self.delete_selection(True, textview.get_editable()) 

    def select_all(self) :
        start,end = self.get_bounds()
        self.select_range(start, end)

    def set_fg_color(self, c) :
        print "setting fg color"
   
    def set_bg_color(self, c) :
        print "setting bg color"

    def toggleBold(self) :
        self.toggleTag(self.bold_tag)

    def toggleItalics(self) :
        self.toggleTag(self.italic_tag)

    def toggleUnderline(self) :
        self.toggleTag(self.underline_tag)

    def toggleStrikethrough(self) :
        print "toggling strikethrough"

    def toggleTag(self, tag) :
        if self.get_selection_bounds() != () : # Toggle for existing text
            start, end = self.get_selection_bounds()
            if (start.has_tag(tag) or (end.has_tag(tag) and not end.begins_tag(tag))) :
                self.remove_tag(tag, start, end)
            else :
                self.apply_tag(tag, start, end)
        else : # Toggle for future text input
            try :
                index = (i for i in xrange(len(self.active_tags)) if self.active_tags[i] == tag).next()
                del self.active_tags[index]
            except StopIteration:
                self.active_tags.append(tag)

    def font_change(self, new_font) :
        # Remove old font from active tags
        try :
            index = (i for i in xrange(len(self.active_tags)) if self.active_tags[i] == self.font_tag).next()
            del self.active_tags[index]
        except StopIteration:
            pass
        # Also remove from tag table
        self.get_tag_table().remove(self.font_tag)

        # Change the tag to affect future text
        self.font_tag = self.create_tag("Font", font=new_font)
        self.active_tags.append(self.font_tag)

        # Apply to current selection
        if self.get_selection_bounds() != () :
            begin, end = self.get_selection_bounds()
            self.apply_tag(self.font_tag, begin, end)

    def select(self, bounds):
        start, stop = bounds
        self.select_range(start, stop)

    def find(self, find, backward, wrap):
        iter = self.get_iter_at_mark(self.get_insert())
        wrapped = False

        if iter.is_end() == True and wrap == True:
            wrapped = True
            iter = self.get_start_iter()

        if backward == True:
            res = iter.backward_search(find, gtk.TEXT_SEARCH_TEXT_ONLY)
        else:
            res = iter.forward_search(find, gtk.TEXT_SEARCH_TEXT_ONLY)

        if res:
            if res[0].equal(iter) == True and wrapped == False:
                self.place_cursor(res[1])
                return self.find(find, backward, wrap)
            self.select(res)
            return res
        else:
            self.place_cursor(self.get_end_iter())

        return None

    def replace(self, find, replace, backward, wrap):
        res = self.find(find, backward, wrap)
        if res:
            self.delete(res[0], res[1])
            self.insert(res[0], replace)
        return res

    def replaceAll(self, find, replace) :
        res = self.replace(find, replace, False, True)
        while res is not None:
            res = self.replace(find, replace, False, True)

    def on_text_inserted(self, buffer, iter, text, length, data=None) :
        # If length is > 1 then the user probably pasted something -- keep source formatting
        if length == 1 :
            start = iter.copy()
            start.backward_chars(length)
            end = iter.copy()
            end.forward_char()
            for tag in self.active_tags :
                self.apply_tag(tag, start, end)

    def wipe_tags(self) :
        table = self.get_tag_table()

        for t in ['Bold', 'Underline', 'Font', 'Italic', 'link'] :
            while (table.lookup(t) is not None) :
              tag = table.lookup(t)
              table.remove(tag)

        while len(self.active_tags) > 0 :
            del self.active_tags[0]

    def recreate_bold(self) :
        self.bold_tag = self.create_tag("Bold", weight=pango.WEIGHT_BOLD)

    def recreate_italic(self) :
        self.italic_tag = self.create_tag("Italic", style=pango.STYLE_ITALIC)

    def recreate_underline(self) :
        self.underline_tag = self.create_tag("Underline", underline=pango.UNDERLINE_SINGLE)

    def recreate_font(self) :
        self.font_tag = self.create_tag("Font", font="Sans 10")
        self.font_tag.set_priority(0)

    def recreate_link(self) :
        self.link_tag = self.create_tag("link", foreground='blue', underline=pango.UNDERLINE_SINGLE)
        self.link_tag.set_priority(3)
